package com.optitronics.beans;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;

import com.optitronics.util.OptitronicsConstants;

@Configurable
@Entity
@Table(name = "administrators")
public class Administrator {

	@PersistenceContext
	transient EntityManager entityManager;

	@Id
	@TableGenerator(name = "administratorGenerator", pkColumnValue = "ADMINISTRATORS", table = OptitronicsConstants.COUNTER_TABLE_NAME, pkColumnName = OptitronicsConstants.COUNTER_PK_COLUMN_NAME, valueColumnName = OptitronicsConstants.COUNTER_VALUE_COLUMN_NAME, allocationSize = OptitronicsConstants.COUNTER_ALLOCATION_SIZE)
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "administratorGenerator")
	@Column(name = "ID")
	private Integer id;

	@Version
	@Column(name = "VERSION")
	private Integer version;

	@Column(name = "USERNAME", length = 50)
	@NotNull
	private String username;

	@Column(name = "PASSWORD", length = 150)
	@NotNull
	private String password;

	@Column(name = "FIRST_NAME", length = 50)
	@NotNull
	private String firstName;

	@Column(name = "LAST_NAME", length = 50)
	@NotNull
	private String lastName;

	public Integer getVersion() {
		return this.version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("Version: ").append(getVersion()).append(", ");
		sb.append("Username: ").append(getUsername()).append(", ");
		sb.append("Password: ").append(getPassword()).append(", ");
		sb.append("FirstName: ").append(getFirstName()).append(", ");
		sb.append("LastName: ").append(getLastName()).append(", ");
		sb.append("Id: ").append(getId());
		return sb.toString();
	}

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Transactional
	public void persist() {
		if (this.entityManager == null)
			this.entityManager = entityManager();
		this.entityManager.persist(this);
	}

	@Transactional
	public void remove() {
		if (this.entityManager == null)
			this.entityManager = entityManager();
		if (this.entityManager.contains(this)) {
			this.entityManager.remove(this);
		} else {
			Administrator attached = this.entityManager.find(this.getClass(), this.id);
			this.entityManager.remove(attached);
		}
	}

	@Transactional
	public void flush() {
		if (this.entityManager == null)
			this.entityManager = entityManager();
		this.entityManager.flush();
	}

	@Transactional
	public Administrator merge() {
		if (this.entityManager == null)
			this.entityManager = entityManager();
		Administrator merged = this.entityManager.merge(this);
		this.entityManager.flush();
		return merged;
	}

	public static final EntityManager entityManager() {
		EntityManager em = new Administrator().entityManager;
		if (em == null)
			throw new IllegalStateException(
					"Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
		return em;
	}

	public static long countAdministrators() {
		return entityManager().createQuery("select count(o) from Administrator o", Long.class).getSingleResult();
	}

	@SuppressWarnings("unchecked")
	public static Administrator findByUsername(String username) {

		String queryString = "SELECT a FROM Administrator a WHERE a.username = :username";

		List<Administrator> resultList = entityManager().createQuery(queryString).setParameter("username", username)
				.getResultList();
		return resultList.isEmpty() ? null : resultList.get(0);
	}

	public static List<Administrator> findAllAdministrators() {
		return entityManager().createQuery("select o from Administrator o", Administrator.class).getResultList();
	}

	public static Administrator findAdministrator(Integer id) {
		if (id == null)
			return null;
		return entityManager().find(Administrator.class, id);
	}

	public static List<Administrator> findAdministratorEntries(int firstResult, int maxResults) {
		return entityManager().createQuery("select o from Administrator o", Administrator.class)
				.setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
	}
}
